import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;


public class MultiEchoServer {
	private static Semaphore semaphore = new Semaphore(1);
	public static void main(String[] args){
		try{
			ServerSocket serverSocket = new ServerSocket(6789);
			System.out.println("Socket established on 6789");

			
			/*
			 * newCachedThreadPool can support numerous clients, I've tested it
			 * for 3, but I'm sure it could handle more. Messages all received by 
			 * server when they're sent, not much waiting at all.			 * 
			 */
			ExecutorService cachedExecutor = Executors.newCachedThreadPool();
			
			/*
			 * newFixedThreadPool(1), whomever connects first can send messages
			 * first. Others can also send messages, but these will not be echoed
			 * by the server until the client infront of them has quit.
			 */
			
			//ExecutorService fixedExecutor = Executors.newFixedThreadPool(1);
			
			
			//ExecutorService threadExecutor = Executors.newSingleThreadExecutor();



			while(true){
				
				//newCachedThreadPool
				System.out.println("Awaiting connections...");
				Socket connectionSocket = serverSocket.accept();
				semaphore.acquire();
				Thread.sleep(5000);
				cachedExecutor.execute(new handleClient(connectionSocket));
				System.out.println("Connection accepted");
				
				//newFixedThreadPool(1)
				/*System.out.println("Awaiting connections...");
				Socket connectionSocket = serverSocket.accept();
				semaphore.acquire();
				fixedExecutor.execute(new hClient(connectionSocket));
				System.out.println("Connection accepted");
				*/
				
				//newSingleThreadExecutor
				/*System.out.println("Awaiting connections...");
				Socket connectionSocket = serverSocket.accept();
				semaphore.acquire();
				threadExecutor.execute(new hClient(connectionSocket));
				System.out.println("Connection accepted");*/
			   
				semaphore.release();
			}
	}
		
		catch (Exception e){}
	}	
	



}
